﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Xna.Framework;

namespace avemeGame01.SpriteClasses
{
    public enum AnimationKey { Move }

    public class Animation
    {
        #region Fields

        // The Rectangles for each frame used in this animation
        private Rectangle[] frames;
        // The time since we last updated the frame
        TimeSpan frameTimer;
        // The time we display a frame until the next one
        TimeSpan frameLength;
        // The index of the current frame we are displaying
        private int currentFrame;
        // The width in pixel needed to calculatethe frames of the animation
        private int frameWidth;
        // The hight in pixel needed to calculate the frames of the animation
        private int frameHeight;
        // The amount of frames shown per second
        private int framesPerSecond;

        #endregion

        #region Properties

        /// <summary>
        /// The current frame rectangle which should be drawn
        /// </summary>
        public Rectangle CurrentFrameRect
        {
            get { return frames[currentFrame]; }
        }

        /// <summary>
        /// The current frame, clamped to avoid "out of bounds" error
        /// </summary>
        public int CurrentFrame
        {
            get { return currentFrame; }
            set
            {
                currentFrame = (int)MathHelper.Clamp(value, 0, frames.Length - 1);
            }
        }

        /// <summary>
        /// The amount of frames shown per second. Clamped to 1 to 60 because less than 1 makes no sense
        /// and the game does 60 draws per second as a maximum.
        /// </summary>
        public int FramesPerSecond
        {
            get { return framesPerSecond; }
            set
            {
                if (value < 1)
                    framesPerSecond = 1;
                else if (value > 60)
                    framesPerSecond = 60;
                else
                    framesPerSecond = value;
                // calculate how long a frame will be displayed
                frameLength = TimeSpan.FromSeconds(1 / (double)framesPerSecond);
            }
        }

        /// <summary>
        /// The width of the frame in pixel
        /// </summary>
        public int FrameWidth
        {
            get { return frameWidth; }
        }

        /// <summary>
        /// The hight of the frame in pixel
        /// </summary>
        public int FrameHeight
        {
            get { return frameHeight; }
        }

        #endregion

        #region Constructor

        // TODO Maybe need to add X and Y Offsets for frame strips that have multiple frames in vertical order
        public Animation(int frameCount, int frameWidth, int frameHeight, int framesPerSecond)
        {
            // create array with length based on the amount of frames used in this animation
            frames = new Rectangle[frameCount];

            this.frameWidth = frameWidth;
            this.frameHeight = frameHeight;

            for (int i = 0; i < frameCount; i++)
            {
                frames[i] = new Rectangle(
                        (frameWidth * i),
                        0,
                        frameWidth,
                        frameHeight);
            }
            FramesPerSecond = framesPerSecond;
            Reset();
        }

        #endregion

        #region Method Region

        public void Update(GameTime gameTime)
        {
            // Update the elapsed time
            frameTimer += gameTime.ElapsedGameTime;

            // If the elapsed time is larger than the frame length time, move to the next frame
            if (frameTimer >= frameLength)
            {
                // Reset elapsed time
                frameTimer = TimeSpan.Zero;
                // move to next frame and if it is the last frame of the animation set to 0 again
                currentFrame = (currentFrame + 1) % frames.Length;
            }
        }

        /// <summary>
        /// Resets the animation to the beginning meaning the first frame and restart the timers.
        /// </summary>
        public void Reset()
        {
            currentFrame = 0;
            frameTimer = TimeSpan.Zero;
        }

        #endregion
    }
}